import PnUtil from './PnUtil'
import store from '../store/index'
import EventBus from '../utils/EventBus'
import _ from 'lodash'
import { Message, Notice } from 'view-design'

/**
 * 构建 功能组件数据源相关字段对象
 * @param customObj 自定义合并对象（同名字段会覆盖原有字段）
 */
const buildFuncCompDatasourceField = function (customObj = {}) {
  let dsFieldObj = {
    ds_type: 'static',
    ds_apiPath: '',
    ds_apiMethod: 'GET',
    ds_apiHeaders: {},
    ds_apiPostData: {},
    ds_wsPath: '',
    ds_database: '',
    ds_sql: 'select * from ',
    ds_shareDatasourceKey: '', // 对应共享数据源
    ds_csvDatasourceName: '', // CSV数据源名称
    ds_resultObjTemplate: [

    ],
    ds_resultObj: [

    ],
    ds_useFilter: false,  // 是否使用过滤器
    ds_filterCode: '',
    ds_linkageUrlParams: [],
    ds_useTimer: false, // 是否使用定时器
    ds_autoRefresh: false, // 是否开启定时器自动刷新
    ds_autoRefreshDuration: 5,
    ds_useHttpServerProxy: false, // 是否使用服务器代理调用
    ds_dynamicDatasourceSuccessCallbackCode: '', // 动态数据源执行成功回调代码
    ds_controlledMode: false, // 受控模式，默认关闭
    ds_invokeResultClipping: false, // 启用结果集裁剪
    ds_ResultClippingLimit: 50, // 结果集裁剪限制数量
  };
  dsFieldObj = PnUtil.deepMerge(dsFieldObj, customObj);
  return dsFieldObj
};

/**
 * 构建 功能组件通用配置字段
 * @param customObj 自定义合并对象（同名字段会覆盖原有字段）
 */
const buildFuncCompGlobalField = function (customObj = {}) {
  let fieldObj = {
    customGlobalJsCode: '', // 全局脚本，也是初始化运行脚本
    customStyleCode: '{\n}'
  };
  fieldObj = PnUtil.deepMerge(fieldObj, customObj);
  return fieldObj
};

/********************************Echarts相关数据构建********************************/
/**
 * 构建 Echart图表组件自定义配置对象以及一些公共配置
 * @returns {{customOption: string}}
 */
const buildEchartCompCustomOption = function () {
  let fieldObj = {
    customOption: '{\n}',
    dataItemClickJsCode: '',  // 数据项点击时运行脚本
    renderer: 'canvas', // Echarts渲染模式
    echartsSpreadingCode: '', // 扩展代码
  };
  return fieldObj
};

const buildChartLegendPosition = function (position) {
  let obj = {};
  switch (position) {
    case 'top-left':
      obj.left = 'left';
      break;
    case 'top-center':
      obj.left = 'center';
      break;
    case 'top-right':
      obj.left = 'right';
      break;
    case 'bottom-left':
      obj.left = 'left';
      obj.bottom = '0';
      break;
    case 'bottom-center':
      obj.left = 'center';
      obj.bottom = '0';
      break;
    case 'bottom-right':
      obj.left = 'right';
      obj.bottom = '0';
      break;
  }
  return obj
};

/* title */
const buildTitleConfigData = function (otherConfig) {
  return PnUtil.deepMerge({
    show: false,
    text: '',
    link: '',
    target: 'blank',
    textStyle: {
      color: '#fff',
      fontSize: 18,
      textShadowColor: '',
      textShadowBlur: 0
    },
    subtext: '',
    sublink: '',
    subtarget: 'blank',
    subtextStyle: {
      color: '#e0e0e0',
      fontSize: 12,
      textShadowColor: '',
      textShadowBlur: 0
    },
    itemGap: 8,
    left: 'auto',
    top: 'auto',
    right: 'auto',
    bottom: 'auto'
  }, otherConfig)
}

const buildTitleChartOption = function (titleConfigData) {
  if (!titleConfigData) return {}
  return {
    show: titleConfigData.show,
    text: titleConfigData.text,
    link: titleConfigData.link,
    target: titleConfigData.target,
    textStyle: {
      color: titleConfigData.textStyle.color,
      fontSize: titleConfigData.textStyle.fontSize,
      textShadowColor: titleConfigData.textStyle.textShadowColor,
      textShadowBlur: titleConfigData.textStyle.textShadowBlur
    },
    subtext: titleConfigData.subtext,
    sublink: titleConfigData.sublink,
    subtarget: titleConfigData.subtarget,
    subtextStyle: {
      color: titleConfigData.subtextStyle.color,
      fontSize: titleConfigData.subtextStyle.fontSize,
      textShadowColor: titleConfigData.subtextStyle.textShadowColor,
      textShadowBlur: titleConfigData.subtextStyle.textShadowBlur
    },
    itemGap: titleConfigData.itemGap,
    left: titleConfigData.left,
    top: titleConfigData.top,
    right: titleConfigData.right,
    bottom: titleConfigData.bottom
  }
}

/* grid */
const buildGridConfigData = function (otherConfig) {
  return PnUtil.deepMerge({
    top: '15%',
    left: '5%',
    right: '5%',
    bottom: '5%',
    containLabel: true
  }, otherConfig)
}
const buildGridChartOption = function (gridConfigData) {
  return {
    top: gridConfigData.top,
    left: gridConfigData.left,
    right: gridConfigData.right,
    bottom: gridConfigData.bottom,
    containLabel: gridConfigData.containLabel
  }
}

/* legend */
const buildLegendConfigData = function (otherConfig = {}) {
  return PnUtil.deepMerge({
    show: true,
    type: 'plain',
    position: 'top-center',
    orient: 'horizontal',
    itemGap: 10,
    itemWidth: 25,
    itemHeight: 14,
    textStyle: {
      color: 'rgb(144, 160, 174)',
      fontSize: 12
    },
    icon: 'roundRect'
  }, otherConfig)
}
const buildLegendChartOption = function (legendConfigData) {
  return {
    show: legendConfigData.show,
    type: legendConfigData.type,
    left: buildChartLegendPosition(legendConfigData.position).left,
    bottom: buildChartLegendPosition(legendConfigData.position).bottom,
    orient: legendConfigData.orient,
    itemGap: legendConfigData.itemGap,
    itemWidth: legendConfigData.itemWidth,
    itemHeight: legendConfigData.itemHeight,
    textStyle: {
      color: legendConfigData.textStyle.color,
      fontSize: legendConfigData.textStyle.fontSize
    },
    icon: legendConfigData.icon,
    data: []
  }
}

/* tooltip */
const buildTooltipConfigData = function (otherConfig = {}) {
  return PnUtil.deepMerge({
    show: true,
    trigger: 'axis', // item,axis,none
    triggerOn: 'mousemove',
    axisPointer: {
      type: 'cross',
      lineStyle: {
        color: 'rgba(255, 255, 255, 0.1)',
        width: 1,
        type: 'solid'
      },
      shadowStyle: {
        color: 'rgba(150, 150, 150, 0.3)',
        shadowBlur: 0,
        shadowColor: '#424242'
      },
      crossStyle: {
        color: 'rgba(255, 255, 255, 0.1)',
        width: 1,
        type: 'dashed'
      }
    },
    enterable: false, // 鼠标是否可进入提示框浮层中，默认为false，如需详情内交互，如添加链接，按钮，可设置为 true。
    backgroundColor: 'rgba(50,50,50,0.7)',
    padding: 5,
    borderWidth: 0,
    borderColor: '#333',
    textStyle: {
      color: '#fff',
      fontSize: 14
    }
  }, otherConfig)
}
const buildTooltipChartOption = function (tooltipConfigData) {
  return {
    show: tooltipConfigData.show,
    trigger: tooltipConfigData.trigger,
    triggerOn: tooltipConfigData.triggerOn,
    axisPointer: {
      type: tooltipConfigData.axisPointer.type,
      lineStyle: {
        color: tooltipConfigData.axisPointer.lineStyle.color,
        width: tooltipConfigData.axisPointer.lineStyle.width,
        type: tooltipConfigData.axisPointer.lineStyle.type
      },
      shadowStyle: {
        color: tooltipConfigData.axisPointer.shadowStyle.color,
        shadowBlur: tooltipConfigData.axisPointer.shadowStyle.shadowBlur,
        shadowColor: tooltipConfigData.axisPointer.shadowStyle.shadowColor
      },
      crossStyle: {
        color: tooltipConfigData.axisPointer.crossStyle.color,
        width: tooltipConfigData.axisPointer.crossStyle.width,
        type: tooltipConfigData.axisPointer.crossStyle.type
      }
    },
    enterable: tooltipConfigData.enterable,
    backgroundColor: tooltipConfigData.backgroundColor,
    padding: tooltipConfigData.padding,
    borderWidth: tooltipConfigData.borderWidth,
    borderColor: tooltipConfigData.borderColor,
    textStyle: {
      color: tooltipConfigData.textStyle.color,
      fontSize: tooltipConfigData.textStyle.fontSize
    }
  }
}

/* xAxis */
const buildXAxisConfigData = function (otherConfig = {}) {
  return PnUtil.deepMerge({
    show: true,
    type: 'category',
    boundaryGap: true,
    name: '',
    nameLocation: 'end',
    nameTextStyle: {
      color: 'rgb(144, 160, 174)',
      fontSize: 12
    },
    nameGap: 15,
    nameRotate: 0,
    axisLabel: { // 坐标轴刻度标签
      show: true,
      fontSize: 12,
      color: 'rgb(144, 160, 174)',
      rotate: 0,
      formatter: "(value, index) => {\n  return value\n}"
    },
    axisLine: { // 坐标轴轴线
      show: true,
      lineStyle: {
        color: 'rgba(255, 255, 255, 0.1)',
        width: 1,
        type: 'solid'
      }
    },
    axisTick: { // 坐标轴刻度
      show: false,
      lineStyle: {
        color: 'rgba(255, 255, 255, 0.1)',
        width: 1,
        type: 'solid'
      }
    },
    splitLine: { // 区域分隔线
      show: false,
      lineStyle: {
        color: 'rgba(255, 255, 255, 0.1)',
        width: 1,
        type: 'solid'
      }
    }
  }, otherConfig)
}
const buildXAxisChartOption = function (xAxisConfigData) {
  return {
    show: xAxisConfigData.show,
    type: xAxisConfigData.type,
    boundaryGap: xAxisConfigData.boundaryGap,
    name: xAxisConfigData.name,
    nameLocation: xAxisConfigData.nameLocation,
    nameTextStyle: {
      color: xAxisConfigData.nameTextStyle.color,
      fontSize: xAxisConfigData.nameTextStyle.fontSize
    },
    nameGap: xAxisConfigData.nameGap,
    nameRotate: xAxisConfigData.nameRotate,
    axisLabel: {
      show: xAxisConfigData.axisLabel.show,
      fontSize: xAxisConfigData.axisLabel.fontSize,
      color: xAxisConfigData.axisLabel.color,
      rotate: xAxisConfigData.axisLabel.rotate,
      formatter: xAxisConfigData.axisLabel.formatter ? eval(xAxisConfigData.axisLabel.formatter) : null
    },
    axisLine: {
      show: xAxisConfigData.axisLine.show,
      lineStyle: {
        color: xAxisConfigData.axisLine.lineStyle.color,
        width: xAxisConfigData.axisLine.lineStyle.width,
        type: xAxisConfigData.axisLine.lineStyle.type
      }
    },
    axisTick: {
      show: xAxisConfigData.axisTick.show,
      lineStyle: {
        color: xAxisConfigData.axisTick.lineStyle.color,
        width: xAxisConfigData.axisTick.lineStyle.width,
        type: xAxisConfigData.axisTick.lineStyle.type
      }
    },
    splitLine: {
      show: xAxisConfigData.splitLine.show,
      lineStyle: {
        color: xAxisConfigData.splitLine.lineStyle.color,
        width: xAxisConfigData.splitLine.lineStyle.width,
        type: xAxisConfigData.splitLine.lineStyle.type
      }
    },
    data: xAxisConfigData.data === undefined ? [] : xAxisConfigData.data
  }
}

/* yAxis */
const buildYAxisConfigData = function (otherConfig = {}) {
  return PnUtil.deepMerge({
    show: true,
    type: 'value',
    name: '',
    nameLocation: 'end',
    nameTextStyle: {
      color: 'rgb(144, 160, 174)',
      fontSize: 12
    },
    nameGap: 15,
    nameRotate: 0,
    inverse: false, // 反向坐标轴
    valueScope: { // 自定义范围显示
      use: false,
      min: -1000,
      max: 1000
    },
    valueInterval: { // 强制设置坐标轴分割间隔
      use: false,
      interval: 100
    },
    axisLabel: { // 坐标轴刻度标签
      show: true,
      fontSize: 12,
      color: 'rgb(144, 160, 174)',
      rotate: 0,
      formatter: '{value}'
    },
    axisLine: { // 坐标轴轴线
      show: true,
      lineStyle: {
        color: 'rgba(255, 255, 255, 0.1)',
        width: 1,
        type: 'solid'
      }
    },
    axisTick: { // 坐标轴刻度
      show: true,
      lineStyle: {
        color: 'rgba(255, 255, 255, 0.1)',
        width: 1,
        type: 'solid'
      }
    },
    splitLine: { // 区域分隔线
      show: false,
      lineStyle: {
        color: 'rgba(255, 255, 255, 0.1)',
        width: 1,
        type: 'solid'
      }
    }
  }, otherConfig)
}
const buildYAxisChartOption = function (yAxisConfigData) {
  let option = {
    show: yAxisConfigData.show,
    type: yAxisConfigData.type,
    name: yAxisConfigData.name,
    nameLocation: yAxisConfigData.nameLocation,
    nameTextStyle: {
      color: yAxisConfigData.nameTextStyle.color,
      fontSize: yAxisConfigData.nameTextStyle.fontSize
    },
    nameGap: yAxisConfigData.nameGap,
    nameRotate: yAxisConfigData.nameRotate,
    inverse: yAxisConfigData.inverse,
    axisLabel: {
      show: yAxisConfigData.axisLabel.show,
      fontSize: yAxisConfigData.axisLabel.fontSize,
      color: yAxisConfigData.axisLabel.color,
      rotate: yAxisConfigData.axisLabel.rotate,
      formatter: yAxisConfigData.axisLabel.formatter
    },
    axisLine: {
      show: yAxisConfigData.axisLine.show,
      lineStyle: {
        color: yAxisConfigData.axisLine.lineStyle.color,
        width: yAxisConfigData.axisLine.lineStyle.width,
        type: yAxisConfigData.axisLine.lineStyle.type
      }
    },
    axisTick: {
      show: yAxisConfigData.axisTick.show,
      lineStyle: {
        color: yAxisConfigData.axisTick.lineStyle.color,
        width: yAxisConfigData.axisTick.lineStyle.width,
        type: yAxisConfigData.axisTick.lineStyle.type
      }
    },
    splitLine: {
      show: yAxisConfigData.splitLine.show,
      lineStyle: {
        color: yAxisConfigData.splitLine.lineStyle.color,
        width: yAxisConfigData.splitLine.lineStyle.width,
        type: yAxisConfigData.splitLine.lineStyle.type
      }
    },
    data: []
  }
  if (yAxisConfigData.valueScope.use) {
    option.min = yAxisConfigData.valueScope.min
    option.max = yAxisConfigData.valueScope.max
  }
  if (yAxisConfigData.valueInterval.use) {
    option.interval = yAxisConfigData.valueInterval.interval
  }
  return option
}

/* series markLine */
const buildMarkLineConfigData = function (otherConfig = {}) {
  return PnUtil.deepMerge({
    silent: true, // 图形是否不响应和触发鼠标事件，默认为 false，即响应和触发鼠标事件。
    symbolSize: 0,
    precision: 2,
    data: []
  }, otherConfig)
}
const buildMarkLineDataItemConfigData = function (otherConfig = {}) {
  return PnUtil.deepMerge({
    type: 'average',
    name: '',
    label: {
      show: true,
      color: '#fff',
      fontSize: 12,
      position: 'end',
      formatter: '{c}'
    },
    lineStyle: {
      color: '#2196f3',
      width: 1,
      type: 'dashed'
    }
  }, otherConfig)
}
const buildMarkLineChartOption = function (markLineConfigData) {
  return {
    silent: markLineConfigData.silent,
    symbolSize: markLineConfigData.symbolSize,
    precision: markLineConfigData.precision,
    data: markLineConfigData.data
  }
}

/* series markPoint */
const buildMarkPointConfigData = function (otherConfig = {}) {
  return PnUtil.deepMerge({
    silent: true, // 图形是否不响应和触发鼠标事件，默认为 false，即响应和触发鼠标事件。
    data: []
  }, otherConfig)
}
const buildMarkPointDataItemConfigData = function (otherConfig = {}) {
  return PnUtil.deepMerge({
    type: 'max',
    name: '',
    symbol: 'pin',
    symbolSize: 40,
    symbolRotate: 0,
    label: {
      show: true,
      position: 'inside',
      rotate: 0,
      color: '#fff',
      fontSize: 12
    },
    itemStyle: {
      color: '',
      borderColor: '#424242',
      borderWidth: 0,
      borderType: 'solid',
      shadowBlur: 0,
      shadowColor: '',
      opacity: 1
    }
  }, otherConfig)
}
const buildMarkPointChartOption = function (markPointConfigData) {
  return {
    symbol: markPointConfigData.symbol,
    symbolSize: markPointConfigData.symbolSize,
    symbolRotate: markPointConfigData.symbolRotate,
    silent: markPointConfigData.silent, // 图形是否不响应和触发鼠标事件，默认为 false，即响应和触发鼠标事件。
    data: markPointConfigData.data
  }
}

const buildVisualMapChartOption = function (visualMapConfigData, itemOtherConfig = {}) {
  if (Object.prototype.toString.call(visualMapConfigData) === '[object Array]') {
    visualMapConfigData.forEach((item, index) => {
      if (item.position) {
        item.left = buildChartLegendPosition(item.position).left
        item.bottom = buildChartLegendPosition(item.position).bottom
      }else {
        item.left = 0
        item.bottom = 0
      }
      Object.assign(item, itemOtherConfig)
    })
  }
  return visualMapConfigData
}
/********************************Echarts相关数据构建 end ********************************/

/**************Echarts图表重绘状态本地存储相关操****************/
const getRedrawChartRunning = function (key) {
  return JSON.parse(sessionStorage.getItem('redrawChartRunning'))[key]
};

const setRedrawChartRunning = function (key, value) {
  if (sessionStorage.getItem('redrawChartRunning')) {
    let obj = JSON.parse(sessionStorage.getItem('redrawChartRunning'));
    obj[key] = value;
    sessionStorage.setItem('redrawChartRunning', JSON.stringify(obj))
  }else {
    let obj = {};
    obj[key] = value;
    sessionStorage.setItem('redrawChartRunning', JSON.stringify(obj))
  }
};

const deleteRedrawChartRunning = function (key) {
  let obj = JSON.parse(sessionStorage.getItem('redrawChartRunning'));
  delete obj[key];
  sessionStorage.setItem('redrawChartRunning', JSON.stringify(obj))
};
/**************Echart图表重绘状态本地存储相关操 end ****************/

/********************************BMap相关数据构建********************************/

const buildBMapOptionConfigData = function (otherConfig = {}) {
  return PnUtil.deepMerge({
    mapType: 'BMAP_NORMAL_MAP',
    styleJson: '',
    center: [108, 38],
    centerCity: '',
    zoom: 5,
    heading: 0,
    tilt: 30,
    skyColors: ['rgba(0,0,0,0)','rgba(33,150,243,0.3)'],

    dragging: true, // 地图拖拽
    scrollWheelZoom: true, // 滚轮放大缩小
    doubleClickZoom: true, // 双击放大
  }, otherConfig)
}

/********************************BMap相关数据构建 end ********************************/

/**
 * 合并图表组件的Option与扩展配置
 * @param option 需要合并的源option
 * @param customOptionString 扩展配置字符
 * @returns {*}
 */
const mergeChartCustomOption = function (option, customOptionString) {
  let customizer = function (objValue, srcValue) {
    if (_.isString(objValue) || _.isBoolean(objValue) || _.isInteger(objValue) || _.isNumber(objValue)) {
      return srcValue
    }
    if (_.isArray(objValue)) {
      _.mergeWith(objValue, srcValue, customizer)
    }
    if (_.isObject(objValue)) {
      _.mergeWith(objValue, srcValue, customizer)
    }
  };

  if (!customOptionString) {
    customOptionString = '{}'
  }

  try {
    return _.mergeWith(PnUtil.deepClone(option), PnUtil.deepClone(JSON.parse(customOptionString)), customizer);
  }catch (e) {
    Message.error({
      duration: 5,
      content: '扩展配置合并错误，可能原因：扩展配置JSON不合规'
    })
  }
};

/********************************************内置交互流相关代码********************************************/

/**
 * 构建 组件内置交互流根配置
 * @param stream
 * @returns
 */
const buildFuncCompInteractionConfiguration = function (stream = []) {
  return {
    // interaction_sender: false,  // 是否开启内置交互数据发送人
    // interaction_receive: false, // 是否开启内置交互数据接收人
    // interaction_fieldsMap: fieldsMap
    interaction_receive: false,
    interaction_stream: stream
  }
}

/**
 * 构建 组件内置交互流项配置
 * @param fieldsMap
 * @returns {{interaction_sender: boolean, interaction_fieldsMap: *[], interaction_key: string}}
 */
const buildFuncCompInteractionStreamItem = function (key = '', fieldsMap = []) {
  return {
    interaction_key: key,
    interaction_sender: false,
    interaction_fieldsMap: fieldsMap
  }
}

/**
 * 构建 组件内置交互流项的字段映射配置
 * @param fieldName 被映射字段名
 * @param bindingVariateName 绑定变量名
 * @param remark 备注
 * @returns
 */
const buildFuncCompInteractionFieldsMapItem = function (fieldName = '', bindingVariateName = '', remark = '') {
  return {
    fieldName: fieldName,
    bindingVariateName: bindingVariateName,
    remark: remark
  }
}

/**
 * 加载页面源数据之后初始化内置交互源数据（暂时不用）
 * @param pageMetadata
 */
const loadPageInitInteractionSourceData = function (pageMetadata) {
  if (pageMetadata) {
    let layoutItems = pageMetadata.layout.layoutItems;
    for (let i=0; i < layoutItems.length; i++) {
      if (layoutItems[i].component.id) {
        if (layoutItems[i].component.compConfigData.interaction_fieldsMap) {
          let interactionSourceData = store.getters['common/getInteractionSourceData'];
          layoutItems[i].component.compConfigData.interaction_fieldsMap.forEach(fm => {
            if (fm.bindingVariateName) {
              interactionSourceData[fm.bindingVariateName] = fm.defaultValue;
            }
          })
          store.commit('common/setInteractionSourceData', interactionSourceData)
        }
      }
    }
  }
}

/**
 * 替换字符串中的内置交互流交互变量以及JS动态脚本
 * @param sourceValue
 * @returns {*}
 */
const replaceStringSourceInteractionFields = function (sourceValue) {
  let interactionVariableObjs = sourceValue.match(/\{{(.+?)\}}/g);
  let interactionSourceData = store.getters['common/getInteractionSourceData'];
  if (interactionVariableObjs) {
    interactionVariableObjs.forEach(ivo => {
      let keyStr = ivo.replace('{{', '').replace('}}', '');
      // 此处判断{{}}中是否含有js:的引用脚本，且不包含'|'符号，如果为真则直接运行脚本
      if (keyStr.indexOf('js:') > -1 && keyStr.indexOf('|') < 0) {
        sourceValue = sourceValue.replace(ivo, eval(keyStr.replace('js:', '')))
      }else {
        let keyStrSplits = keyStr.split('|')
        if (keyStrSplits.length > 1) {
          sourceValue = sourceValue.replace(ivo, interactionSourceData[keyStrSplits[0]] ? interactionSourceData[keyStrSplits[0]] : keyStrSplits[1].indexOf('js:') > -1 ? eval(keyStrSplits[1].replace('js:', '')) : keyStrSplits[1]);
        }else {
          sourceValue = sourceValue.replace(ivo, interactionSourceData[keyStr] ? interactionSourceData[keyStr] : '');
        }
      }
    });
  }
  return sourceValue
}

/**
 * 替换对象中的内置交互流交互变量
 * @param sourceValue
 */
const replaceObjectSourceInteractionFields = function (sourceValue) {
  sourceValue = JSON.stringify(sourceValue);
  sourceValue = replaceStringSourceInteractionFields(sourceValue);
  return JSON.parse(sourceValue)
}

/**
 * 发起内置交互流
 * @param compConfigData
 * @param interaction_key
 * @param sendObj
 */
const launchInteractionStream = function (compConfigData, interaction_key, sendObj) {
  let interactionStreamItem = _.find(compConfigData.interaction_stream, {interaction_key: interaction_key})
  if (interactionStreamItem && interactionStreamItem.interaction_sender) {
    interactionStreamItem.interaction_fieldsMap.forEach(fm => {
      if (fm.bindingVariateName) {
        store.commit('common/setInteractionSourceDataItem', {key: fm.bindingVariateName, value: sendObj[fm.fieldName]})
      }
    })
    EventBus.$emit('pn_interaction_stream', interactionStreamItem.interaction_fieldsMap)
  }
}

/********************************************内置交互流相关代码 end ********************************************/

/********************************************鼠标交互相关代码********************************************/

/**
 * 构建 鼠标交互根配置
 * @returns {{mouse_interaction: []}}
 */
const buildMouseInteractionConfiguration = function () {
  return {
    mouse_interaction: []
  }
}

/**
 * 构建 鼠标交互项配置
 * @param mouseType
 * @returns {{animationDelay: number, action: string, mouseType: string, target: [], animationType: string}}
 */
const buildMouseInteractionItem = function (mouseType = 'click') {
  return {
    mouseType: mouseType,
    action: 'toggle', // show,hide,toggle
    target: [],
    animationType: 'normal', // normal,slide,fade
    animationDelay: 300
  }
}

/**
 * 发起鼠标交互
 * @param compConfigData
 * @param mouseType
 */
const launchMouseInteraction = function (compConfigData, mouseType) {
  if (mouseType) {
    let mouseInteraction = PnUtil.deepClone(compConfigData.mouse_interaction);
    if (mouseInteraction) {
      EventBus.$emit('pn_mouse_interaction', _.filter(mouseInteraction, {mouseType: mouseType}))
    }
  }else {
    Message.warning('发起的鼠标交互事件未指定事件类型')
  }
}

/********************************************鼠标交互相关代码 end ********************************************/

/**
 * 数据源结果集字段映射过滤
 * @param compConfigData
 * @param originalDsResultObj
 * @returns {*}
 */
const dsResultObjMappingFilter = function (compConfigData, originalDsResultObj) {
  let ds_resultObj = PnUtil.deepClone(originalDsResultObj);

  // 字段映射过滤
  if (compConfigData.ds_resultObjTemplate && Array.isArray(compConfigData.ds_resultObjTemplate) && _.some(compConfigData.ds_resultObjTemplate, 'mappingField')) {
    compConfigData.ds_resultObjTemplate.forEach(item => {
      if (item.mappingField && item.mappingField != item.field) {
        if (Array.isArray(ds_resultObj)) {
          ds_resultObj.forEach(resultObjItem => {
            if (resultObjItem[item.mappingField]) {
              resultObjItem[item.field] = resultObjItem[item.mappingField]
            }
          })
        }
      }
    })
  }

  return ds_resultObj
}

/**
 * 数据源结果集自定义过滤器过滤
 * @param compConfigData
 * @param originalDsResultObj
 * @returns {*}
 */
const dsResultObjCustomCodeFilter = function (compConfigData, originalDsResultObj) {
  let ds_resultObj = PnUtil.deepClone(originalDsResultObj);
  // 自定义过滤器过滤
  if (compConfigData.ds_useFilter) {
    if (compConfigData.ds_filterCode) {
      try{
        // 判断过滤器脚本中是否存在'return '字符串，如果存在则使用Function方式去执行过滤器，否则使用eval
        // if (compConfigData.ds_filterCode.indexOf('return ') > -1) {
        //   let fn = new Function('ds_resultObj', compConfigData.ds_filterCode)
        //   return fn(ds_resultObj)
        // }else {
        //   eval(compConfigData.ds_filterCode);
        //   return ds_resultObj
        // }
        eval(compConfigData.ds_filterCode);
        return ds_resultObj
      } catch (e) {
        // 不能加下面这一段，否则会造成过滤器中语法出现错误的时候，页面会卡死的问题（具体原因暂时不明，后续再进行优化）
        // Notice.error({
        //   title: '过滤器运行错误',
        //   desc: e.message,
        //   duration: 8
        // })
        console.error(e)
        // 如果过滤器语法报错，那么直接返回传入的originalDsResultObj结果集对象
        return originalDsResultObj
      }
    } else {
      return ds_resultObj
    }
  }
  return ds_resultObj
}

/**
 * 结果集裁剪
 * @param compConfigData
 * @param originalDsResultObj
 */
const dsResultObjClipping = function (compConfigData, originalDsResultObj) {
  if (compConfigData.ds_invokeResultClipping && Array.isArray(originalDsResultObj)) {
    return originalDsResultObj.slice(0, compConfigData.ds_ResultClippingLimit || 50)
  }
  return originalDsResultObj
}

export default {
  buildFuncCompDatasourceField,
  buildFuncCompGlobalField,

  buildEchartCompCustomOption,
  buildChartLegendPosition,
  buildTitleConfigData,
  buildTitleChartOption,
  buildGridConfigData,
  buildGridChartOption,
  buildLegendConfigData,
  buildLegendChartOption,
  buildTooltipConfigData,
  buildTooltipChartOption,
  buildXAxisConfigData,
  buildXAxisChartOption,
  buildYAxisConfigData,
  buildYAxisChartOption,
  buildMarkLineConfigData,
  buildMarkLineDataItemConfigData,
  buildMarkLineChartOption,
  buildMarkPointConfigData,
  buildMarkPointDataItemConfigData,
  buildMarkPointChartOption,
  buildVisualMapChartOption,

  getRedrawChartRunning,
  setRedrawChartRunning,
  deleteRedrawChartRunning,

  buildBMapOptionConfigData,

  mergeChartCustomOption,

  buildFuncCompInteractionConfiguration,
  buildFuncCompInteractionStreamItem,
  buildFuncCompInteractionFieldsMapItem,
  loadPageInitInteractionSourceData,
  replaceStringSourceInteractionFields,
  replaceObjectSourceInteractionFields,
  launchInteractionStream,

  buildMouseInteractionConfiguration,
  buildMouseInteractionItem,
  launchMouseInteraction,

  dsResultObjMappingFilter,
  dsResultObjCustomCodeFilter,
  dsResultObjClipping
}
